package com.pulse.base.service.impl;

import com.pulse.base.domain.CircuitMeasure;
import com.pulse.base.domain.JobDispatch;
import com.pulse.base.domain.UserTestParam;
import com.pulse.base.domain.vo.ParamVo;
import com.pulse.base.mapper.JobDispatchMapper;
import com.pulse.base.service.ICircuitMeasureService;
import com.pulse.base.service.IJobDispatchService;
import com.pulse.base.service.IUserTestParamService;
import com.pulse.common.annotation.DataScope;
import com.pulse.common.core.redis.RedisCache;
import com.pulse.common.exception.ServiceException;
import com.pulse.common.utils.DateUtils;
import com.pulse.common.utils.SecurityUtils;
import com.pulse.quartz.domain.SysJob;
import com.pulse.quartz.service.ISysJobService;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class JobDispatchServiceImpl implements IJobDispatchService {

    @Autowired
    private JobDispatchMapper jobDispatchMapper;
    @Autowired
    private IUserTestParamService userTestParamService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ICircuitMeasureService circuitMeasureService;
    @Autowired
    private ISysJobService sysJobService;

    /**
     * 启动测试
     *
     * @param circuitMeasure
     * @return
     */
    @Override
    public CircuitMeasure startTest(CircuitMeasure circuitMeasure) {

        UserTestParam userTestParam = userTestParamService.getTestParam(circuitMeasure.getDeviceNo(),circuitMeasure.getChannel());
        if (userTestParam == null) {
            userTestParam = new UserTestParam();
            userTestParam.setDeviceNo(circuitMeasure.getDeviceNo());
            userTestParam.setChannel(circuitMeasure.getChannel());
            userTestParam.setParamTestTime(circuitMeasure.getParamTestTime());
            userTestParam.setParamPw(circuitMeasure.getParamPw());
            userTestParam.setParamRd(circuitMeasure.getParamRd());
            userTestParam.setParamIor(circuitMeasure.getParamIor());
            userTestParam.setParamTestMode(circuitMeasure.getParamTestMode());
            userTestParam.setParamBackScatter(circuitMeasure.getParamBackScatter());
            userTestParam.setParamFinalThreshold(circuitMeasure.getParamFinalThreshold());
            userTestParam.setParamReflectThreshold(circuitMeasure.getParamReflectThreshold());
            userTestParam.setParamNonReflectThreshold(circuitMeasure.getParamNonReflectThreshold());
            userTestParam.setParamWaveLength(circuitMeasure.getParamWaveLength());
            userTestParamService.insertUserTestParam(userTestParam);
        } else {
            userTestParam.setParamTestTime(circuitMeasure.getParamTestTime());
            userTestParam.setParamPw(circuitMeasure.getParamPw());
            userTestParam.setParamRd(circuitMeasure.getParamRd());
            userTestParam.setParamIor(circuitMeasure.getParamIor());
            userTestParam.setParamTestMode(circuitMeasure.getParamTestMode());
            userTestParam.setParamBackScatter(circuitMeasure.getParamBackScatter());
            userTestParam.setParamFinalThreshold(circuitMeasure.getParamFinalThreshold());
            userTestParam.setParamReflectThreshold(circuitMeasure.getParamReflectThreshold());
            userTestParam.setParamNonReflectThreshold(circuitMeasure.getParamNonReflectThreshold());
            userTestParam.setParamWaveLength(circuitMeasure.getParamWaveLength());
            userTestParamService.updateUserTestParam(userTestParam);
        }

        // 1 点名测试  2 定期测试  3 复测
        circuitMeasure.setType(1);
        // 0 非参考曲线  1 参考曲线
        circuitMeasure.setDefaultMeasure(0);
        // -1：删除 0：完成 1：待测试 2：待解析 11：测试失败 12：解析失败
        circuitMeasure.setStatus(1);
        circuitMeasure.setCreateTime(DateUtils.getNowDate());
        circuitMeasureService.insertCircuitMeasure(circuitMeasure);
        redisCache.setCacheObject("CircuitMeasure:" + circuitMeasure.getDeviceNo() + "_" + circuitMeasure.getChannel() + "_1"+"_"+circuitMeasure.getMeasureId(),circuitMeasure,10, TimeUnit.MINUTES);
        // 将测试消息发送到缓存列表
        redisCache.push("jobQueue:" + circuitMeasure.getDeviceNo(),
                circuitMeasure.getDeviceNo() + "_" + circuitMeasure.getChannel() + "_1"+"_"+circuitMeasure.getMeasureId());
        return circuitMeasure;
    }

    /**
     * 创建或更新周期测试任务
     *
     * @param jobDispatch
     * @return
     */
    @Override
    public int updateJobDispatch(JobDispatch jobDispatch) {
        Long jobId = jobDispatch.getJobId();
        SysJob sysJob = sysJobService.selectJobById(jobId);
        sysJob.setCronExpression(jobDispatch.getCronExpression());
        try{
            return sysJobService.updateJob(sysJob);
        }
        catch (Exception e){
            throw new ServiceException("更新失败");
        }
    }

    /**
     * 添加周期测试任务
     *
     * @param jobDispatch
     * @return
     */
    @Override
    public int insertJobDispatch(JobDispatch jobDispatch) {
        return jobDispatchMapper.insertJobDispatch(jobDispatch);
    }

    /**
     * 根据设备编号查询
     *
     * @param deviceNo
     * @return
     */
    @Override
    public List<JobDispatch> selectByDeviceNo(String deviceNo) {
        return jobDispatchMapper.selectByDeviceNo(deviceNo);
    }

    /**
     * 根据设备编号和通道号查询
     *
     * @param deviceNo
     * @param channel
     * @return
     */
    @Override
    public JobDispatch selectByDeviceNoAndChannel(String deviceNo, Long channel) {
        return jobDispatchMapper.selectByDeviceNoAndChannel(deviceNo, channel);
    }

    /**
     * 根据设备编号删除
     *
     * @param deviceNo
     * @return
     */
    @Override
    @Transactional
    public int deleteJobDispatchByDeviceNo(String deviceNo) {
        List<JobDispatch> jobDispatchList = jobDispatchMapper.selectByDeviceNo(deviceNo);
        List<Long> jobIds = new ArrayList<>();
        for (JobDispatch jobDispatch : jobDispatchList) {
            jobIds.add(jobDispatch.getJobId());
        }
        try {
            sysJobService.deleteJobByIds(jobIds.toArray(new Long[0]));
        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
        return jobDispatchMapper.deleteByDeviceNo(deviceNo);
    }

    /**
     * 查询任务列表
     *
     * @param jobDispatch
     * @return
     */
    @Override
    @DataScope(deptAlias = "d", userAlias = "u")
    public List<JobDispatch> selectJobDispathList(JobDispatch jobDispatch) {
        return jobDispatchMapper.selectJobDispathList(jobDispatch);
    }

    /**
     * 批量修改cron表达式
     *
     * @param paramVo
     * @return
     */
    @Override
    public int setCron(ParamVo paramVo) {
        for (Long id : paramVo.getIds()) {
            JobDispatch jobDispatch = jobDispatchMapper.selectJobDispatchById(id);
            SysJob job = sysJobService.selectJobById(jobDispatch.getJobId());
            job.setCronExpression(paramVo.getCronExpression());
            job.setUpdateBy(SecurityUtils.getUsername());
            try{
                sysJobService.updateJob(job);
            }
            catch (Exception e)
            {
                throw new ServiceException("设置失败："+e.getMessage());
            }
        }
        return paramVo.getIds().length;
    }
}
